From: Arlo Siemsen Date: Mon, 25 May 2026 07:49:43 +0000 (+0200) Subject: CVE-2026-5222: avoid stripping .git suffix when for non git registries X-Git-Tag: archive/raspbian/1.95.0+dfsg1-2+rpi1^2~1 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi//%22https:/www.google.com/search/%22http:/www.example.com/cgi/%22https:/www.google.com/search?a=commitdiff_plain;h=494b68bc0ce34c3400c8d3dbf47fff6da0078b02;p=rustc.git CVE-2026-5222: avoid stripping .git suffix when for non git registries FG: adapt patches Signed-off-by: Fabian Grünbichler Gbp-Pq: Topic cargo Gbp-Pq: Name CVE-2026-5222-avoid-stripping-.git-suffix-when-for-non-gi.patch --- diff --git a/src/tools/cargo/src/cargo/sources/git/source.rs b/src/tools/cargo/src/cargo/sources/git/source.rs index d6dbe03e4c..a7b3205c83 100644 --- a/src/tools/cargo/src/cargo/sources/git/source.rs +++ b/src/tools/cargo/src/cargo/sources/git/source.rs @@ -470,6 +470,13 @@ mod test { assert_eq!(ident1, ident2); } + #[test] + fn test_canonicalize_idents_does_not_strip_dot_git_for_sparse() { + let ident1 = ident(&src("sparse+https://crates.io/fake-registry")); + let ident2 = ident(&src("sparse+https://crates.io/fake-registry.git")); + assert_ne!(ident1, ident2); + } + fn src(s: &str) -> SourceId { SourceId::for_git(&s.into_url().unwrap(), GitReference::DefaultBranch).unwrap() } diff --git a/src/tools/cargo/src/cargo/util/canonical_url.rs b/src/tools/cargo/src/cargo/util/canonical_url.rs index 7516e03569..2716d2d4f5 100644 --- a/src/tools/cargo/src/cargo/util/canonical_url.rs +++ b/src/tools/cargo/src/cargo/util/canonical_url.rs @@ -33,27 +33,31 @@ impl CanonicalUrl { url.path_segments_mut().unwrap().pop_if_empty(); } - // For GitHub URLs specifically, just lower-case everything. GitHub - // treats both the same, but they hash differently, and we're gonna be - // hashing them. This wants a more general solution, and also we're - // almost certainly not using the same case conversion rules that GitHub - // does. (See issue #84) - if url.host_str() == Some("github.com") { - url = format!("https{}", &url[url::Position::AfterScheme..]) - .parse() - .unwrap(); - let path = url.path().to_lowercase(); - url.set_path(&path); - } + // Perform further canonicalization specific to git registries, which + // do not contain a `+` specifier. + if !url.scheme().contains('+') { + // For GitHub URLs specifically, just lower-case everything. GitHub + // treats both the same, but they hash differently, and we're gonna be + // hashing them. This wants a more general solution, and also we're + // almost certainly not using the same case conversion rules that GitHub + // does. (See issue #84) + if url.host_str() == Some("github.com") { + url = format!("https{}", &url[url::Position::AfterScheme..]) + .parse() + .unwrap(); + let path = url.path().to_lowercase(); + url.set_path(&path); + } - // Repos can generally be accessed with or without `.git` extension. - let needs_chopping = url.path().ends_with(".git"); - if needs_chopping { - let last = { - let last = url.path_segments().unwrap().next_back().unwrap(); - last[..last.len() - 4].to_owned() - }; - url.path_segments_mut().unwrap().pop().push(&last); + // Repos can generally be accessed with or without `.git` extension. + let needs_chopping = url.path().ends_with(".git"); + if needs_chopping { + let last = { + let last = url.path_segments().unwrap().next_back().unwrap(); + last[..last.len() - 4].to_owned() + }; + url.path_segments_mut().unwrap().pop().push(&last); + } } Ok(CanonicalUrl(url))